package main.java.com.lee.cas;

import sun.misc.Unsafe;

import java.lang.reflect.Field;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.stream.IntStream;

/**
 * @Description TODO
 * @Author winston
 * @DateTime 2021/12/27
 */
public class CasSafeIncrement {

    static class test{
        static Unsafe unsafe ;
        static long offset=0;
        private volatile int sum=0;

        static {
            try {

                Class klass = Unsafe.class;
                Field field = klass.getDeclaredField("theUnsafe");
                field.setAccessible(true);
                unsafe = (Unsafe) field.get(null);
                offset = unsafe.objectFieldOffset(test.class.getDeclaredField("sum"));
                System.out.println("sum偏移量: " + offset);
            } catch (NoSuchFieldException | IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        public void multiThreadStart() throws InterruptedException {
            ExecutorService executorService = Executors.newFixedThreadPool(10);

            CountDownLatch countDownLatch = new CountDownLatch(10);
            for (int i = 1; i <= 10; i++) {
                executorService.submit(() -> {
                    cyclePlus();
                });
                countDownLatch.countDown();
            }
            countDownLatch.await();
            executorService.shutdown();
            int i = 0;
            while (!executorService.isTerminated()) {
                i++;
                System.out.println("第: "+i+"次检查线程池是否关闭");
            }
            System.out.println(sum);
        }

        public void cyclePlus() {
            System.out.println(Thread.currentThread().getName());
            for (int i = 1; i <= 10000; i++) {
                int oldValue = sum;
                int atmp = 0;
                do {
                    oldValue = sum;
                    if (atmp > 1) {
                        System.out.println("第: "+(atmp-1)+"重试次数");
                    }
                    atmp++;
                } while (!unsafeCAS(oldValue, oldValue + 1));
            }
        }

        public boolean unsafeCAS(int oldValue, int newValue) {
            return unsafe.compareAndSwapInt(this, offset, oldValue, newValue);
        }

        public static void main(String[] args) throws InterruptedException {
            test test = new test();
            test.multiThreadStart();
        }
    }

}
